<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>单例模式设计模式详解 | 技术小馆</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            background-color: #f9f9f9;
            line-height: 1.6;
        }
        h1, h2, h3, h4, h5, h6 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
        }
        .code-block {
            font-family: 'Courier New', monospace;
            background-color: #2d2d2d;
            color: #f8f8f2;
            border-radius: 0.5rem;
        }
        .highlight {
            position: relative;
        }
        .highlight::before {
            content: '';
            position: absolute;
            left: 0;
            bottom: 0;
            width: 100%;
            height: 50%;
            background-color: rgba(167, 119, 227, 0.1);
            z-index: -1;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-4xl text-center">
            <div class="inline-block bg-white bg-opacity-20 px-4 py-2 rounded-full mb-6">
                <span class="text-sm font-medium">创建型设计模式</span>
            </div>
            <h1 class="text-4xl md:text-5xl font-bold mb-6 leading-tight">单例模式 <span class="text-yellow-300">Singleton Pattern</span></h1>
            <p class="text-xl md:text-2xl opacity-90 max-w-3xl mx-auto mb-8">
                确保一个类只有一个实例，并提供一个全局访问点
            </p>
            <div class="flex justify-center space-x-4">
                <a href="#overview" class="px-6 py-3 bg-white text-purple-700 rounded-full font-medium hover:bg-opacity-90 transition">开始探索</a>
                <a href="#implementation" class="px-6 py-3 border-2 border-white text-white rounded-full font-medium hover:bg-white hover:bg-opacity-10 transition">实现方式</a>
            </div>
        </div>
    </section>

    <!-- Overview Section -->
    <section id="overview" class="py-16 px-4 md:px-0">
        <div class="container mx-auto max-w-4xl">
            <div class="flex items-center mb-12">
                <div class="h-1 bg-purple-600 flex-1"></div>
                <h2 class="text-3xl font-bold px-6 text-center">模式概述</h2>
                <div class="h-1 bg-purple-600 flex-1"></div>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8 mb-16">
                <div>
                    <h3 class="text-2xl font-semibold mb-4 text-purple-700">核心概念</h3>
                    <p class="mb-6">单例模式是一种创建型设计模式，其主要目的是确保一个类只有一个实例，并提供一个全局访问点。</p>
                    <p>在许多实际应用中非常有用，特别是在需要控制资源访问、管理全局状态或共享资源的场景中。</p>
                </div>
                <div>
                    <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
                        <div class="flex items-center mb-4">
                            <div class="bg-purple-100 p-3 rounded-full mr-4">
                                <i class="fas fa-lightbulb text-purple-600 text-xl"></i>
                            </div>
                            <h4 class="text-xl font-semibold">典型应用场景</h4>
                        </div>
                        <ul class="space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                                <span>数据库连接池</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                                <span>配置管理器</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                                <span>日志记录器</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                                <span>缓存系统</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                                <span>线程池</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
            
            <!-- UML Diagram -->
            <div class="mb-16">
                <h3 class="text-2xl font-semibold mb-6 text-center">单例模式UML类图</h3>
                <div class="bg-white rounded-xl shadow-lg p-6 overflow-x-auto">
                    <pre class="mermaid">
                        classDiagram
                            class Singleton {
                                -static instance: Singleton
                                -Singleton()
                                +static getInstance() Singleton
                            }
                    </pre>
                </div>
            </div>
            
            <!-- Pros & Cons -->
            <div class="grid md:grid-cols-2 gap-8 mb-16">
                <!-- Pros -->
                <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
                    <div class="flex items-center mb-6">
                        <div class="bg-green-100 p-3 rounded-full mr-4">
                            <i class="fas fa-thumbs-up text-green-600 text-xl"></i>
                        </div>
                        <h3 class="text-2xl font-semibold text-green-700">优点</h3>
                    </div>
                    <ul class="space-y-4">
                        <li>
                            <h4 class="font-medium text-lg mb-1">全局访问</h4>
                            <p class="text-gray-600">确保类只有一个实例，提供全局访问点，便于访问和管理共享资源</p>
                        </li>
                        <li>
                            <h4 class="font-medium text-lg mb-1">节省资源</h4>
                            <p class="text-gray-600">减少内存开销和资源消耗，适合频繁使用的资源</p>
                        </li>
                        <li>
                            <h4 class="font-medium text-lg mb-1">避免重复实例化</h4>
                            <p class="text-gray-600">所有客户端使用同一个实例，避免对象重复创建</p>
                        </li>
                        <li>
                            <h4 class="font-medium text-lg mb-1">控制共享资源</h4>
                            <p class="text-gray-600">集中控制共享资源访问，避免多实例间的冲突</p>
                        </li>
                        <li>
                            <h4 class="font-medium text-lg mb-1">延迟加载</h4>
                            <p class="text-gray-600">懒汉式实现可延迟加载，提高程序启动性能</p>
                        </li>
                    </ul>
                </div>
                
                <!-- Cons -->
                <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
                    <div class="flex items-center mb-6">
                        <div class="bg-red-100 p-3 rounded-full mr-4">
                            <i class="fas fa-exclamation-triangle text-red-600 text-xl"></i>
                        </div>
                        <h3 class="text-2xl font-semibold text-red-700">缺点</h3>
                    </div>
                    <ul class="space-y-4">
                        <li>
                            <h4 class="font-medium text-lg mb-1">并发问题</h4>
                            <p class="text-gray-600">多线程环境下可能导致线程安全问题，需要同步机制</p>
                        </li>
                        <li>
                            <h4 class="font-medium text-lg mb-1">全局状态</h4>
                            <p class="text-gray-600">全局实例可能带来全局状态问题，难以调试维护</p>
                        </li>
                        <li>
                            <h4 class="font-medium text-lg mb-1">测试困难</h4>
                            <p class="text-gray-600">单元测试难以隔离单例实例的影响</p>
                        </li>
                        <li>
                            <h4 class="font-medium text-lg mb-1">继承问题</h4>
                            <p class="text-gray-600">通常限制类的继承，设计为final类或无合适构造方法</p>
                        </li>
                        <li>
                            <h4 class="font-medium text-lg mb-1">内存泄漏风险</h4>
                            <p class="text-gray-600">单例对象生命周期长，可能一直占用内存</p>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </section>

    <!-- Implementation Section -->
    <section id="implementation" class="py-16 px-4 md:px-0 bg-gray-50">
        <div class="container mx-auto max-w-4xl">
            <div class="flex items-center mb-12">
                <div class="h-1 bg-purple-600 flex-1"></div>
                <h2 class="text-3xl font-bold px-6 text-center">实现方式</h2>
                <div class="h-1 bg-purple-600 flex-1"></div>
            </div>
            
            <!-- Tabs Navigation -->
            <div class="flex flex-wrap justify-center mb-8">
                <button class="tab-btn active px-6 py-3 font-medium text-purple-700 border-b-2 border-purple-700" data-tab="lazy">懒汉式</button>
                <button class="tab-btn px-6 py-3 font-medium text-gray-500 hover:text-purple-700 border-b-2 border-transparent" data-tab="eager">饿汉式</button>
                <button class="tab-btn px-6 py-3 font-medium text-gray-500 hover:text-purple-700 border-b-2 border-transparent" data-tab="double-check">双重检查</button>
                <button class="tab-btn px-6 py-3 font-medium text-gray-500 hover:text-purple-700 border-b-2 border-transparent" data-tab="static-holder">静态内部类</button>
            </div>
            
            <!-- Tab Contents -->
            <div class="tab-content active" id="lazy">
                <div class="bg-white rounded-xl shadow-lg overflow-hidden">
                    <div class="p-6">
                        <h3 class="text-2xl font-semibold mb-4 text-purple-700">懒汉式 (Lazy Initialization)</h3>
                        <p class="mb-6">在第一次使用时才创建实例，适用于对资源的延迟加载需求。需要注意线程安全问题，一般使用 <code class="bg-gray-100 px-2 py-1 rounded">synchronized</code> 关键字来实现。</p>
                        
                        <div class="mb-6">
                            <h4 class="font-medium text-lg mb-2">特点</h4>
                            <ul class="list-disc pl-5 space-y-1">
                                <li>延迟加载，节省启动资源</li>
                                <li>需要同步机制保证线程安全</li>
                                <li>首次访问可能略有延迟</li>
                            </ul>
                        </div>
                        
                        <div class="code-block p-6 rounded-lg mb-4">
                            <pre class="text-sm">
public class LazySingleton {
    private static LazySingleton instance;
    
    private LazySingleton() {}
    
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}</pre>
                        </div>
                    </div>
                    <div class="bg-gray-100 px-6 py-4 border-t border-gray-200">
                        <div class="flex items-center text-sm">
                            <i class="fas fa-info-circle text-purple-600 mr-2"></i>
                            <span>注意：同步方法会导致性能下降，每次获取实例都需要同步。</span>
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="tab-content hidden" id="eager">
                <div class="bg-white rounded-xl shadow-lg overflow-hidden">
                    <div class="p-6">
                        <h3 class="text-2xl font-semibold mb-4 text-purple-700">饿汉式 (Eager Initialization)</h3>
                        <p class="mb-6">在类加载时就创建实例，确保实例在类加载完成后即被创建。简单易实现，但可能导致资源浪费，尤其是在实例创建成本高时。</p>
                        
                        <div class="mb-6">
                            <h4 class="font-medium text-lg mb-2">特点</h4>
                            <ul class="list-disc pl-5 space-y-1">
                                <li>类加载时就初始化，没有线程安全问题</li>
                                <li>实现简单直接</li>
                                <li>可能造成资源浪费</li>
                            </ul>
                        </div>
                        
                        <div class="code-block p-6 rounded-lg mb-4">
                            <pre class="text-sm">
public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();
    
    private EagerSingleton() {}
    
    public static EagerSingleton getInstance() {
        return instance;
    }
}</pre>
                        </div>
                    </div>
                    <div class="bg-gray-100 px-6 py-4 border-t border-gray-200">
                        <div class="flex items-center text-sm">
                            <i class="fas fa-info-circle text-purple-600 mr-2"></i>
                            <span>适用于创建成本不高且需要频繁使用的单例对象。</span>
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="tab-content hidden" id="double-check">
                <div class="bg-white rounded-xl shadow-lg overflow-hidden">
                    <div class="p-6">
                        <h3 class="text-2xl font-semibold mb-4 text-purple-700">双重检查锁定 (Double-Check Locking)</h3>
                        <p class="mb-6">结合懒汉式和饿汉式的优点，通过双重检查锁定减少了同步开销。实现复杂，但可以提高性能和线程安全性。</p>
                        
                        <div class="mb-6">
                            <h4 class="font-medium text-lg mb-2">特点</h4>
                            <ul class="list-disc pl-5 space-y-1">
                                <li>延迟加载与线程安全的平衡</li>
                                <li>减少同步开销</li>
                                <li>需要volatile关键字保证可见性</li>
                            </ul>
                        </div>
                        
                        <div class="code-block p-6 rounded-lg mb-4">
                            <pre class="text-sm">
public class DoubleCheckSingleton {
    private volatile static DoubleCheckSingleton instance;
    
    private DoubleCheckSingleton() {}
    
    public static DoubleCheckSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckSingleton();
                }
            }
        }
        return instance;
    }
}</pre>
                        </div>
                    </div>
                    <div class="bg-gray-100 px-6 py-4 border-t border-gray-200">
                        <div class="flex items-center text-sm">
                            <i class="fas fa-info-circle text-purple-600 mr-2"></i>
                            <span>Java 5及以上版本中，volatile关键字能确保正确的内存可见性。</span>
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="tab-content hidden" id="static-holder">
                <div class="bg-white rounded-xl shadow-lg overflow-hidden">
                    <div class="p-6">
                        <h3 class="text-2xl font-semibold mb-4 text-purple-700">静态内部类 (Initialization-on-demand holder idiom)</h3>
                        <p class="mb-6">利用静态内部类的特性实现懒加载，同时保证线程安全性。现代Java环境中推荐的实现方式，既简单又线程安全。</p>
                        
                        <div class="mb-6">
                            <h4 class="font-medium text-lg mb-2">特点</h4>
                            <ul class="list-disc pl-5 space-y-1">
                                <li>延迟加载且线程安全</li>
                                <li>实现简单优雅</li>
                                <li>现代Java推荐方式</li>
                            </ul>
                        </div>
                        
                        <div class="code-block p-6 rounded-lg mb-4">
                            <pre class="text-sm">
public class StaticHolderSingleton {
    private StaticHolderSingleton() {}
    
    private static class Holder {
        static final StaticHolderSingleton INSTANCE = new StaticHolderSingleton();
    }
    
    public static StaticHolderSingleton getInstance() {
        return Holder.INSTANCE;
    }
}</pre>
                        </div>
                    </div>
                    <div class="bg-gray-100 px-6 py-4 border-t border-gray-200">
                        <div class="flex items-center text-sm">
                            <i class="fas fa-info-circle text-purple-600 mr-2"></i>
                            <span>利用JVM类加载机制保证线程安全，无需额外同步。</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Comparison Section -->
    <section class="py-16 px-4 md:px-0">
        <div class="container mx-auto max-w-4xl">
            <h2 class="text-3xl font-bold text-center mb-12">单例模式实现方式对比</h2>
            
            <div class="overflow-x-auto">
                <table class="min-w-full bg-white rounded-lg overflow-hidden shadow-lg">
                    <thead class="bg-purple-700 text-white">
                        <tr>
                            <th class="py-3 px-4 text-left">实现方式</th>
                            <th class="py-3 px-4 text-left">线程安全</th>
                            <th class="py-3 px-4 text-left">延迟加载</th>
                            <th class="py-3 px-4 text-left">性能</th>
                            <th class="py-3 px-4 text-left">复杂度</th>
                        </tr>
                    </thead>
                    <tbody class="divide-y divide-gray-200">
                        <tr>
                            <td class="py-4 px-4 font-medium">懒汉式</td>
                            <td class="py-4 px-4">需要同步</td>
                            <td class="py-4 px-4">是</td>
                            <td class="py-4 px-4">较低</td>
                            <td class="py-4 px-4">低</td>
                        </tr>
                        <tr class="bg-gray-50">
                            <td class="py-4 px-4 font-medium">饿汉式</td>
                            <td class="py-4 px-4">是</td>
                            <td class="py-4 px-4">否</td>
                            <td class="py-4 px-4">高</td>
                            <td class="py-4 px-4">最低</td>
                        </tr>
                        <tr>
                            <td class="py-4 px-4 font-medium">双重检查</td>
                            <td class="py-4 px-4">是</td>
                            <td class="py-4 px-4">是</td>
                            <td class="py-4 px-4">高</td>
                            <td class="py-4 px-4">中</td>
                        </tr>
                        <tr class="bg-gray-50">
                            <td class="py-4 px-4 font-medium">静态内部类</td>
                            <td class="py-4 px-4">是</td>
                            <td class="py-4 px-4">是</td>
                            <td class="py-4 px-4">高</td>
                            <td class="py-4 px-4">低</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </section>

    <!-- Best Practices Section -->
    <section class="py-16 px-4 md:px-0 bg-gray-50">
        <div class="container mx-auto max-w-4xl">
            <div class="flex items-center mb-12">
                <div class="h-1 bg-purple-600 flex-1"></div>
                <h2 class="text-3xl font-bold px-6 text-center">最佳实践</h2>
                <div class="h-1 bg-purple-600 flex-1"></div>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
                    <div class="flex items-center mb-4">
                        <div class="bg-blue-100 p-3 rounded-full mr-4">
                            <i class="fas fa-check-circle text-blue-600 text-xl"></i>
                        </div>
                        <h3 class="text-xl font-semibold">使用场景建议</h3>
                    </div>
                    <ul class="space-y-3">
                        <li class="flex items-start">
                            <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                            <span>当类必须只有一个实例且客户端需要从全局访问点访问它时</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                            <span>当需要控制共享资源的访问时</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                            <span>当实例创建成本高且需要频繁使用时</span>
                        </li>
                    </ul>
                </div>
                
                <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
                    <div class="flex items-center mb-4">
                        <div class="bg-yellow-100 p-3 rounded-full mr-4">
                            <i class="fas fa-exclamation-triangle text-yellow-600 text-xl"></i>
                        </div>
                        <h3 class="text-xl font-semibold">注意事项</h3>
                    </div>
                    <ul class="space-y-3">
                        <li class="flex items-start">
                            <i class="fas fa-times text-red-500 mt-1 mr-2"></i>
                            <span>避免过度使用单例模式，可能导致代码难以测试和维护</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-times text-red-500 mt-1 mr-2"></i>
                            <span>注意线程安全问题，特别是在多线程环境中</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-times text-red-500 mt-1 mr-2"></i>
                            <span>考虑使用依赖注入框架替代单例模式</span>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </section>

    <!-- Footer -->
    <footer class="bg-gray-900 text-white py-12 px-4">
        <div class="container mx-auto max-w-4xl text-center">
            <h3 class="text-xl font-semibold mb-4">技术小馆</h3>
            <p class="text-gray-400 mb-6">探索设计模式的奥秘，提升软件开发艺术</p>
            <a href="http://www.yuque.com/jtostring" class="inline-block px-6 py-2 border border-gray-600 rounded-full hover:bg-gray-800 transition">访问语雀主页</a>
            <div class="mt-8 text-gray-500 text-sm">
                <p>© 2023 技术小馆. 保留所有权利.</p>
            </div>
        </div>
    </footer>

    <!-- Scripts -->
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <script>
        mermaid.initialize({ startOnLoad: true });
        
        // Tab functionality
        document.querySelectorAll('.tab-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                // Remove active class from all buttons and contents
                document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active', 'text-purple-700', 'border-purple-700'));
                document.querySelectorAll('.tab-btn').forEach(b => b.classList.add('text-gray-500', 'border-transparent'));
                document.querySelectorAll('.tab-content').forEach(c => c.classList.add('hidden'));
                
                // Add active class to clicked button and corresponding content
                btn.classList.add('active', 'text-purple-700', 'border-purple-700');
                btn.classList.remove('text-gray-500', 'border-transparent');
                document.getElementById(btn.dataset.tab).classList.remove('hidden');
            });
        });
    </script>
</body>
</html>